// Motion Editor (position and radius of disk interpolating timed keyframes)

CLOUD C = new CLOUD(2); // keyframes edited by user
int k=0;  // current keys
float f=0; // frame
float df=0.01; // frame increment
Boolean animating=true, useM=false, threeD=false,inter = false;

void MYsetup() {
  C.declarePoints(); 
  C.resetPoints();
}

void MYmenu () {
  scribeFooter("p:play animation, f:film animation, t:change time (drag mouse), 3:3D, 2:2D", 2);
  scribeFooter("m:move, r:rotate, z:zoom, _:append, a:angle, c:weightChange, x:delete, s:save, l:load, =:reset", 1);
}

void MYdraw () {
  if (threeD) {
    directionalLight(250, 250, 250, 20, 100, -100);
    pushMatrix();
    translate(width/2, height/2, height/2-mouseY); 
    rotateX(70*PI/180);
    rotateZ(PI*(mouseX-300)/400);
    translate(-width/2, -height/2, 0); 

    //        translate(0.0, 9.0, (300-mouseY)/4);
    //        rotateX(75*PI/180);

    C.drawKeys3D(); 
    C.drawPickedKeys3D();
    popMatrix();
  }
  else {
    stroke(orange); 
    noFill(); 
    C.drawKeys(); 
    C.drawPickedKeys();
    fill(black); 
    C.writePointIDs(); 
    noFill(); 
    //  showFrame(f);
    if(inter){
      stroke(blue); 
      displayFrames();
    }
  }
  if (capturing) captureFrame(); // when filming and '.' was pressed, we want to capture all animation frames into the film
  if (animating) {
   animateFrame(f); 
    f+=df;  
    if (f>1) {
      f=0; 
      capturing=false;
    }
  } // advance time if animating and stop capturing when reached the end
}

void MYmouseMoved() {
}  // executed when the mouse is moved (not dragged): mouse button is not pressed but the location changed

void MYmousePressed() {  // executed when the mouse is pressed
  if (!Mouse().isInWindow()) return; // do nothing if pressed out of the window (can change that method of pt to restric where one can click
  if (!keyPressed || key=='a' )  C.pickClosestPoint(Mouse()); // used to pick the closest vertex of C to the mouse
  else {
    if (key==' ') C.appendPoint(Mouse()); // insert a new vertex in C
    if (key=='x') { 
      C.pickClosestPoint(Mouse()); 
      C.deletePoint();
    } // delete the closest vertex
    if (key=='c') { 
      C.pickClosestPoint(Mouse()); 
      C.weightChange();
    }
  }
}

void MYmouseDragged() {
  if (!keyPressed) {
    C.dragPoint();
  } // drag selected point with mouse
  if (keyPressed) {
    if (key=='t') f+=float(mouseX-pmouseX)/width;  // adjust current frame   
    if (key=='m') C.translatePoints(MouseDrag()); // rotate all points around their center of mass
    if (key=='r') C.rotatePointsAroundCenterOfMass(Mouse(), Pmouse()); // rotate all points around their center of mass
    if (key=='a') C.rotateOrientation(); // rotate all points around their center of mass
    if (key=='z') C.scalePointsAroundCenterOfMass(Mouse(), MouseDrag()); // scale all points with respect to their center of mass
  }
}  

void MYmouseReleased() {
}  

void MYkeyPressed() {
  if (key=='p') {
    animating=!animating; 
    f=0;
  }   // toggles playing animation
  if (key=='f') {
    capturing=true; 
    animating=true; 
    f=0;
  }
  if (key=='l') {
    C.loadPts();
  }
  if (key=='=') {
    C.resetPoints();
  }
  if (key=='s') C.savePts(); 
  if (key=='3') threeD=true;
  if (key=='2') threeD=false;
  if (key == 'i') inter=!inter;
}  

void  MYkeyReleased() {
}

void displayFrames(){
   for(int i = 1; i <= 29 ; i ++){
      displayFrame(C.first(), C.last(), C.orientation(0),C.orientation(1), (float)i/29);
   }
}

void animateFrame(float i){
  displayFrame(C.first(), C.last(), C.orientation(0),C.orientation(1), i);
}

void displayFrame(pt a, pt b, float aA, float bA, float s){
    float t = sin(s * PI/2);
    pt P = new pt(interPolate(a.x, t, b.x), interPolate(a.y, t, b.y));
    float w = interPolateA(aA, t, bA);
    float w2 = interPolateA(aA, s, bA);
    if(inter){
      drawInter(P,w);
    }else{
      drawDancerAni(P, w) ;
      if(s < 0.5 ){
        drawFeetAni(new pt(interPolate(a.x, 2*s, b.x), interPolate(a.y, 2*s, b.y)),w2,true); 
        drawFeetAni(new pt(interPolate(a.x, 0, b.x), interPolate(a.y, 0, b.y)),aA,false); 
      }else if(s < 1){
        drawFeetAni(new pt(interPolate(a.x, 1, b.x), interPolate(a.y, 1, b.y)),bA,true); 
        drawFeetAni(new pt(interPolate(a.x, 2*s - 1, b.x), interPolate(a.y, 2*s - 1, b.y)),w2,false); 
      }
    }
}

float interPolateA(float a, float t, float b){
  return a%TWO_PI + t *(b%TWO_PI-a%TWO_PI);
}

float interPolate(float a, float t, float b){
  return a + t *(b-a);
}

float interPolateFeet(float a, float t, float b){
  return 0.0;
}
